/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import Entidad.Cliente;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author alexis
 */
public class ClienteDAO {

    private static final String SQL_INSERT =
            "INSERT INTO clientes ("
            + "fecha_registro, nombre_cliente, abreviatura, identificacion, tipo_de_identificacion, telefonos, "
            + "telefonos_certificado_retenciones, fax, correspondencia, devolucion_de_muestras, envio_de_resultados, "
            + "facturacion, direccion, ciudad, condiciones_de_facturacion, persona_contacto, "
            + "emails_autorizados_resultados, emails_comunicacion_retencion"
            + ") VALUES (?, ?, ?, ?,?, ?, ?, ?, ?,?, ?, ?, ?, ?,?, ?, ?, ?)";
    
    private static final String SQL_SELECT =
            "SELECT * "
            + "  FROM clientes where id_cliente= ?";
    
    private static final String SQL_SELECT_All =
            "SELECT * "
            + "FROM clientes";
    
    private static final String SQL_UPDATE =
            "UPDATE clientes SET "
            + "fecha_registro = ?, nombre_cliente = ?, abreviatura = ?, identificacion = ?, tipo_de_identificacion = ?, "
            + "telefonos = ?, telefonos_certificado_retenciones = ?, fax = ?, correspondencia = ?, devolucion_de_muestras = ?, "
            + "envio_de_resultados = ?, facturacion = ?, direccion = ?, ciudad = ?, condiciones_de_facturacion = ?, "
            + "persona_contacto = ?, emails_autorizados_resultados = ?, emails_comunicacion_retencion = ?"
            + " WHERE "
            + "id_cliente = ? ";

    private static final String SQL_DELETE =
            "DELETE FROM clientes WHERE "
            + "id_cliente = ?";
    
    private static final String SELECCIONAR_ABREVIATURA =
            "SELECT * FROM clientes WHERE "
            + "abreviatura = ?";
    
    private static final String SELECCIONAR_NOMBRE =
            "SELECT * FROM clientes WHERE "
            + "nombre_cliente = ?";
    
    private static final String SELECCIONAR_IDENTIFICACION =
            "SELECT * FROM clientes WHERE "
            + "identificacion = ?";
    
    private static final String SELECCIONAR_ID =
            "SELECT id_cliente FROM clientes WHERE "
            + "nombre_cliente = ?";
    
    private static final String INSERTAR_ULTIMA_MUESTRA =
            "INSERT INTO ultima_muestra ("
            + "clientes_id_cliente, muestra_numero) "
            + "VALUES (?, ?)";
    
    private static final String SELECCIONAR_ULTIMA_MUESTRA =
            "SELECT muestra_numero FROM ultima_muestra WHERE "
            + "clientes_id_cliente = ?";
    
    private static final String SHOW_TABLE_STATUS =
            "SHOW TABLE STATUS LIKE 'clientes'";
    
    private static final String ACTUALIZAR_ULTIMA_MUESTRA =
            "UPDATE ultima_muestra SET "
            + "muestra_numero = ? "
            + "WHERE clientes_id_cliente = ?";
    
    public void create(Cliente clt, Connection conn) throws SQLException {

        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(SQL_INSERT);
           // ps.setInt(1, clt.getIdtabla());
            ps.setDate(1, clt.getFechaRegistro());
            ps.setString(2, clt.getNombre());
            ps.setString(3,clt.getAbreviatura());
            ps.setString(4,clt.getIdentificacion());
            ps.setString(5,clt.getTipoIdentificacion());
            ps.setString(6,clt.getTelefonos());
            ps.setString(7,clt.getTelefonosCertificados());
            ps.setString(8,clt.getFax());
            ps.setBoolean(9,clt.getCorrespondencia());
            ps.setBoolean(10,clt.getDevolucionMuestras());
            ps.setBoolean(11,clt.getEnvioResultados());
            ps.setBoolean(12,clt.getFacturacion());
            ps.setString(13,clt.getDireccion());
            ps.setString(14,clt.getCiudad());
            ps.setString(15,clt.getCondicionesFacturacion());
            ps.setString(16,clt.getPersonaContacto());
            ps.setString(17,clt.getEmailsResultados());
            ps.setString(18,clt.getEmailsComunicacion());
            ps.executeUpdate();
            insertarUltimaMuestra(siguienteIDCliente(conn) - 1, 0, conn);
        } finally {
            cerrar(ps);
        }
    }

    public Cliente load(Cliente clt, Connection conn) throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(SQL_SELECT);
            ps.setInt(1, clt.getIdCliente());
            rs = ps.executeQuery();
            List results = getResults(rs);
            if (results.size() > 0) {
                return (Cliente)results.get(0);
            } else {
                return null;
            }
        } finally {
            cerrarRs(rs);
            cerrar(ps); 
        }
   }

    public List loadAll(Connection conn) throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(SQL_SELECT_All);
            rs = ps.executeQuery();
            List results = getResults(rs);
            if (results.size() > 0) {
                return results;
            } else {
                return null;
            }
        } finally {
            cerrarRs(rs);
            cerrar(ps);
        }
    }

    public void update(Cliente clt, Connection conn) throws SQLException {
        PreparedStatement ps = null;
        try {
            /*            
            ps = conn.prepareStatement(SQL_UPDATE);
            ps.setString(1, clt.getDescripcion());
            ps.setDouble(2, dto.getPrecio());
            ps.setInt(3, clt.getExistencias());
            ps.setString(4, dto.getClaveArticulo());
            ps.executeUpdate();*/
            ps = conn.prepareStatement(SQL_UPDATE);
            //ps.setInt(1, clt.getIdtabla());
            ps.setDate(1, clt.getFechaRegistro());
            ps.setString(2, clt.getNombre());
            ps.setString(3,clt.getAbreviatura());
            ps.setString(4,clt.getIdentificacion());
            ps.setString(5,clt.getTipoIdentificacion());
            ps.setString(6,clt.getTelefonos());
            ps.setString(7,clt.getTelefonosCertificados());
            ps.setString(8,clt.getFax());
            ps.setBoolean(9,clt.getCorrespondencia());
            ps.setBoolean(10,clt.getDevolucionMuestras());
            ps.setBoolean(11,clt.getEnvioResultados());
            ps.setBoolean(12,clt.getFacturacion());
            ps.setString(13,clt.getDireccion());
            ps.setString(14,clt.getCiudad());
            ps.setString(15,clt.getCondicionesFacturacion());
            ps.setString(16,clt.getPersonaContacto());
            ps.setString(17,clt.getEmailsResultados());
            ps.setString(18,clt.getEmailsComunicacion());
            ps.executeUpdate();
            
        } finally {
            cerrar(ps);
        }
    }

    public void delete(Cliente clt, Connection conn) throws SQLException {
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(SQL_DELETE);
            ps.setInt(1, clt.getIdCliente());
            ps.executeUpdate();
        } finally {
            cerrar(ps);
        }
    }

    private List getResults(ResultSet rs) throws SQLException {
        List results = new ArrayList();
        while (rs.next()) {
            Cliente clt = new Cliente();
            clt.setIdCliente(rs.getInt("id_cliente"));
            clt.setFechaRegistro(rs.getDate("fecha_registro"));
            clt.setNombre(rs.getString( "nombre_cliente"));
            clt.setAbreviatura(rs.getString("abreviatura"));
            clt.setIdentificacion(rs.getString("identificacion"));
            clt.setTipoIdentificacion(rs.getString("tipo_de_identificacion"));
            clt.setTelefonos(rs.getString("telefonos"));
            clt.setTelefonosCertificados(rs.getString("telefonos_certificado_retenciones"));
            clt.setFax(rs.getString("fax"));
            clt.setCorrespondencia(rs.getBoolean("correspondencia"));
            clt.setDevolucionMuestras(rs.getBoolean("devolucion_de_muestras"));
            clt.setEnvioResultados(rs.getBoolean("envio_de_resultados"));
            clt.setFacturacion(rs.getBoolean("facturacion"));
            clt.setDireccion(rs.getString("direccion"));
            clt.setCiudad(rs.getString("ciudad"));
            clt.setCondicionesFacturacion(rs.getString("condiciones_de_facturacion"));
            clt.setPersonaContacto(rs.getString("persona_contacto"));
            clt.setEmailsResultados(rs.getString("emails_autorizados_resultados"));
            clt.setEmailsComunicacion(rs.getString("emails_comunicacion_retencion"));
            
            results.add(clt);
        }
        return results;
    }
    
    public boolean existeAbreviatura(String abreviatura, Connection conn) throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(SELECCIONAR_ABREVIATURA);
            ps.setString(1, abreviatura);
            rs = ps.executeQuery();
            return rs.first();
        } finally {
            cerrarRs(rs);
            cerrar(ps);
        }
    }
    
    public boolean existeCliente(String nombreCliente, Connection conexion) throws SQLException{
        boolean existe = false;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conexion.prepareStatement(SELECCIONAR_NOMBRE);
            ps.setString(1, nombreCliente);
            rs = ps.executeQuery();
            return rs.first();
        } finally {
            cerrarRs(rs);
            cerrar(ps);
        }
    }
    
    public boolean existeIdentificacion(String identificacion, Connection conexion) throws SQLException{
        boolean existe = false;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conexion.prepareStatement(SELECCIONAR_IDENTIFICACION);
            ps.setString(1, identificacion);
            rs = ps.executeQuery();
            return rs.first();
        } finally {
            cerrarRs(rs);
            cerrar(ps);
        }
    }
    
    public int buscarIDCliente(String nombrecliente, Connection conexion) throws Exception {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conexion.prepareStatement(SELECCIONAR_ID);
            ps.setString(1, nombrecliente);
            rs = ps.executeQuery();
            if(rs.first())
                return rs.getInt("id_cliente");
            else
                return 0;
        } finally {
            cerrarRs(rs);
            cerrar(ps);
        }
    }
    
    private int siguienteIDCliente(Connection conexion) throws SQLException{
        int resultado;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conexion.prepareStatement(SHOW_TABLE_STATUS);
            rs = ps.executeQuery();
            if (rs.first()) {
                resultado = rs.getInt("Auto_increment");
            } else {
                resultado = 0;
            }
            return resultado;
        } finally {
            cerrarRs(rs);
            cerrar(ps);
        }
    }
    
    private void insertarUltimaMuestra(int IDCliente, int ultimaMuestra, Connection conexion) throws SQLException{
        PreparedStatement ps = null;
        try {
            ps = conexion.prepareStatement(INSERTAR_ULTIMA_MUESTRA);
            ps.setInt(1, IDCliente);
            ps.setInt(2, ultimaMuestra);
            ps.executeUpdate();
        } finally {
            cerrar(ps);
        }
    }
    
    public void actualizarUltimaMuestra(int IDCliente, int ultimaMuestra, Connection conexion) throws SQLException{
        PreparedStatement ps = null;
        try {
            ps = conexion.prepareStatement(ACTUALIZAR_ULTIMA_MUESTRA);
            ps.setInt(1, ultimaMuestra);
            ps.setInt(2, IDCliente);
            ps.executeUpdate();
        } finally {
            cerrar(ps);
        }
    }
    
    public int seleccionarUltimaMuestra(int IDCliente, Connection conexion) throws SQLException, Exception {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conexion.prepareStatement(SELECCIONAR_ULTIMA_MUESTRA);
            ps.setInt(1, IDCliente);
            rs = ps.executeQuery();
            if (rs.first()) {
                return rs.getInt("muestra_numero");
            } else {
                throw new Exception("No se pudo encontrar la última muestra asignada a este cliente.");
            }
        } finally {
            cerrarRs(rs);
            cerrar(ps); 
        }
   }
     public Cliente eoncontrarClientePorNombre(String abr, Connection conn) throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(SELECCIONAR_NOMBRE);
            ps.setString(1, abr);
            rs = ps.executeQuery();
            List results = getResults(rs);
            if (results.size() > 0) {
                return (Cliente)results.get(0);
            } else {
                return null;
            }
        } finally {
            cerrarRs(rs);
            cerrar(ps);  
        }
    }
    public Cliente eoncontrarClientePorAbreviatura(String abr, Connection conn) throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(SELECCIONAR_ABREVIATURA);
            ps.setString(1, abr);
            rs = ps.executeQuery();
            List results = getResults(rs);
            if (results.size() > 0) {
                return (Cliente)results.get(0);
            } else {
                return null;
            }
        } finally {
            cerrarRs(rs);
            cerrar(ps);  
        }
    }
    
    public ArrayList<Cliente> buscarClientes(Cliente cliente, Date fechaInicial, Date fechaFinal, Connection conexion) throws Exception{
        String sentencia = "SELECT * from clientes WHERE ";
        ArrayList criterios = new ArrayList();
        
        if (fechaInicial != null)
            criterios.add(String.format(" fecha_registro >= '%s' AND fecha_registro <= '%s'",
                    fechaInicial.toString(), fechaFinal.toString()));
        if (cliente.getNombre() != null)
            criterios.add(" nombre_cliente LIKE '%"+cliente.getNombre()+"%'");
        if (cliente.getAbreviatura() != null)
            criterios.add(String.format(" abreviatura LIKE '%s'", cliente.getAbreviatura()));
        if (cliente.getIdentificacion() != null)
            criterios.add(String.format(" identificacion = '%s'", cliente.getIdentificacion()));
        if (cliente.getTipoIdentificacion() != null)
            criterios.add(String.format(" tipo_de_identificacion = '%s'", cliente.getTipoIdentificacion()));
        if (cliente.getCiudad() != null)
            criterios.add(" ciudad = '"+cliente.getCiudad()+"'");
        if (cliente.getCondicionesFacturacion() != null)
            criterios.add(" condiciones_de_facturacion LIKE '"+cliente.getCondicionesFacturacion()+"%'");
        
        if (!criterios.isEmpty()){
            sentencia += criterios.get(0);
            for (int i = 1; i < criterios.size(); i++) {
                sentencia += " AND" + (String) criterios.get(i);
            }
        }else{
            throw new Exception("No se proporcionaron criterios para buscar.");
        }
        
        PreparedStatement ps = null;
        ResultSet rs = null;
        
        try{
            ps = conexion.prepareStatement(sentencia);
            rs = ps.executeQuery();
            List results = getResults(rs);
            if (results.size() > 0) {
                return (ArrayList<Cliente>) results;
            } else {
                return null;
            }
        } finally {
            cerrarRs(rs);
            cerrar(ps);
        }
    }

    private void cerrar(PreparedStatement ps) throws SQLException {
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
            }
        }
    }

    private void cerrarRs(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
            }
        }
    }

    public void cerrarCnn(Connection cnn) {
        if (cnn != null) {
            try {
                cnn.close();
            } catch (SQLException e) {
            }
        }
    }
}